package com.sztz.excel;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.style.AbstractCellStyleStrategy;
import com.sztz.constants.CommonConstants;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Workbook;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 实现Excel单元格样式为符点数
 * @author yzy
 * @date 2023/1/5 16:07
 */
public class CellStyleForFmtStrategy extends AbstractCellStyleStrategy {
    /**
     * 当前需要处理的workbook对象
     */
    private Workbook workbook;
    /**
     * 需要处理的列号
     * map的key就是类型：Integer,Double
     * map的value就是列号列表，格式{1,3,9}，处理第一列，第3列，第9列
     */
    private Map<String,List<Integer>> columnIndexMap;
    /**
     * 需要处理的行号,格式为{"1-1", "5-8","10-11"} 处理第1行，第5到8行，第10到11行
     */
    private Map<String,List<String>> rowIndexMap;

    public CellStyleForFmtStrategy(Map<String,List<Integer>> columnIndexMap, Map<String,List<String>> rowIndexMap){
        this.columnIndexMap = columnIndexMap;
        this.rowIndexMap = rowIndexMap;
    }
    /**
     * 初始化信息
     * @param workbook 工作表对象
     * @author yzy
     * @date 2023/1/6 9:50
     */
    @Override
    protected void initCellStyle(Workbook workbook) {
        this.workbook = workbook;
    }
    /**
     * 处理表头
     * @param cell 单元格
     * @param head 表头
     * @param relativeRowIndex 行号
     * @author yzy
     * @date 2023/1/6 9:50
     */
    @Override
    protected void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex) {}
    /**
     * 处理表体
     * @param cell 单元格
     * @param head 表头
     * @param relativeRowIndex 行号
     * @author yzy
     * @date 2023/1/6 9:51
     */
    @Override
    protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
        columnIndexMap.keySet().forEach(key->{
            if(needSetCellStyle(cell,relativeRowIndex,key)){
                setCellStyle(cell,key);
            }
        });

    }
    /**
     * 是否需要处理当前单元格样式
     * @param cell 单元格对象
     * @param relativeRowIndex 行号
     * @param key 样式类型key Integer or Double
     * @return boolean
     * @author yzy
     * @date 2023/1/13 9:51
     */
    private boolean needSetCellStyle(Cell cell, Integer relativeRowIndex,String key){
        List<Integer> columnIndexList = columnIndexMap.get(key);
        //如果列号列表是空的，则不用处理单元格样式
        if(CollUtil.isEmpty(columnIndexList)){
            return Boolean.FALSE;
        }
        //满足条件的列的单元格才需要处理
        if(columnIndexList.stream().anyMatch(item->NumberUtil.compare(item,cell.getColumnIndex())==0)){
            //如果没有设置行数，则所有行的单元格都处理
            if(CollUtil.isEmpty(rowIndexMap) || !rowIndexMap.containsKey(key)){
                return Boolean.TRUE;
            }
            //行数未设，或当前行数能匹配设置的行数范围则需要处理单元格样式
            List<String> rowIndexList = rowIndexMap.get(key);
            if(CollUtil.isEmpty(rowIndexList) || rowIndexList.stream().anyMatch(item->rangeIn(relativeRowIndex,item))){
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }

    /**
     * 判断当前行号是否是定义的范围内
     * @param relativeRowIndex 当前行号
     * @param item 行号范围
     * @return boolean
     * @author yzy
     * @date 2023/1/10 16:16
     */
    private boolean rangeIn(Integer relativeRowIndex, String item) {
        if(!StrUtil.contains(item, CharUtil.DASHED)){
            return Boolean.FALSE;
        }
        List<String> split = StrUtil.split(item, StrUtil.DASHED);
        if( !NumberUtil.isInteger(split.get(0)) || !NumberUtil.isInteger(split.get(1)) ){
            return Boolean.FALSE;
        }
        int min = ArrayUtil.min(NumberUtil.parseInt(split.get(0)),NumberUtil.parseInt(split.get(1)));
        int max = ArrayUtil.max(NumberUtil.parseInt(split.get(0)),NumberUtil.parseInt(split.get(1)));
        return Math.max(min,relativeRowIndex) == Math.min(relativeRowIndex,max);
    }

    /**
     * 设置单元格样式为符点数
     * @param cell excel单元格
     * @param key 样式类型key Integer or Double
     * @author yzy
     * @date 2023/1/10 15:41
     */
    private void setCellStyle(Cell cell,String key) {
        //获取单元格的内容
        cell.setCellType(CellType.STRING);
        String cellValue = cell.getStringCellValue();
        //数字类型
        cell.setCellType(CellType.NUMERIC);
        if(StrUtil.isNotBlank(cellValue)){
            CellStyle cellStyle = workbook.createCellStyle();
            switch(key) {
                case CommonConstants.CELL_STYLE_KEY_DOUBLE:
                    //设置格式
                    cell.setCellValue(Double.valueOf(new BigDecimal(cellValue).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()));
                    //格式：0.00 另一种方式也可以: HSSFDataFormat.getBuiltinFormat("0.00")
                    cellStyle.setDataFormat((short) 2);
                    cell.setCellStyle(cellStyle);
                break;
                case CommonConstants.CELL_STYLE_KEY_INTEGER:
                    cell.setCellValue(Integer.parseInt(cellValue));
                    cellStyle.setDataFormat((short)1);
                    break;
                default:

            }
        }
    }
}
